package xxl.robotlegs.extensions.signalcommandmap.impl 
{
	import xxl.robotlegs.extensions.commandcenter.api.ICommandExecutor;
	import xxl.robotlegs.extensions.commandcenter.api.ICommandMappingList;
	import xxl.robotlegs.extensions.commandcenter.api.ICommandTrigger;
	import xxl.robotlegs.extensions.commandcenter.impl.CommandExecutor;
	import xxl.robotlegs.extensions.commandcenter.impl.CommandMapper;
	import xxl.robotlegs.extensions.commandcenter.impl.CommandMappingList;
	import xxl.robotlegs.extensions.commandcenter.impl.CommandPayload;
	import xxl.robotlegs.framework.api.IInjector;
	import xxl.robotlegs.framework.api.ILogger;
	import xxl.signals.api.IMapSignal;
	import xxl.signals.api.IOnceSignal;
	import xxl.signals.api.ISignal;
	/**
	 * ...
	 * @author XXL
	 */
	public class SignalCommandTrigger implements ICommandTrigger
	{
		private var _injector:IInjector;
		private var _signalClass:Class;
		private var _injectName:String;
		private var _mapKey:Object;
		private var _mappings:ICommandMappingList;
		private var _executor:ICommandExecutor;
		
		public function SignalCommandTrigger(
			injector:IInjector,
			signalClass:Class,
			injectName:String = "",
			mapKey:Object = null,
			processors:Array = null,
			logger:ILogger = null) 
		{
			_injector = injector;
			_signalClass = signalClass;
			_injectName = injectName;
			_mapKey = mapKey;
			_mappings = new CommandMappingList(this, processors, logger);
			_executor = new CommandExecutor(injector, _mappings.removeMapping);
		}
		
		public function createMapper():CommandMapper
		{
			return new CommandMapper(_mappings);
		}
		
		private function signalHandler(...args):void
		{
			const signal:IOnceSignal = _injector.getInstance(_signalClass, _injectName);
			_executor.executeCommands(_mappings.getList(), new CommandPayload(args, signal.valueClasses));
		}
		
		/* INTERFACE xxl.robotlegs.extensions.commandcenter.api.ICommandTrigger */
		
		public function activate():void 
		{
			const signal:IOnceSignal = _injector.getInstance(_signalClass, _injectName);
			const useMap:Boolean = (signal is IMapSignal) && _mapKey;
			if (useMap)
			{
				(signal as IMapSignal).addToMap(_mapKey, signalHandler).safelyExecute = false;
			}
			else if (signal is ISignal)
			{
				(signal as ISignal).add(signalHandler).safelyExecute = false;
			}
			else
			{
				signal.addOnce(signalHandler).safelyExecute = false;
			}
		}
		
		public function deactivate():void 
		{
			const signal:IOnceSignal = _injector.getInstance(_signalClass, _injectName);
			const useMap:Boolean = (signal is IMapSignal) && _mapKey;
			if (useMap)
			{
				(signal as IMapSignal).removeFromMap(_mapKey, signalHandler);
			}
			else if (signal is ISignal)
			{
				signal.remove(signalHandler);
			}
		}
		
	}

}